using System;
using UnityEditor;
using UnityEngine;

namespace FShaderInspector
{
    public partial class FShaderGUI
    {
        /// <summary> 表面选项绘制 </summary>
        void SurfaceOptions()
        {
            var btnRect = GetTempRect();

            // 绘制本地化按钮
            var functionIcon = EditorGUIUtility.IconContent("Font Icon");
            if (Localization.GetLocalize()) functionIcon = EditorGUIUtility.IconContent("Text Icon");
            functionIcon.tooltip = "本地化语言切换。";

            if (GUI.Button(new Rect(btnRect.width - 30, btnRect.y + 1, 29, btnRect.height), functionIcon))
                Localization.SetLocalize(!Localization.GetLocalize());

            var key = EditorCache.instance.GetPropertyKey(_material, "Surface Options");
            var open = EditorCache.instance.GetKey(key);

            // 折页按钮
            if (GUI.Button(btnRect, "", "BoldLabel"))
                EditorCache.instance.SetKey(key, !open);


            var icon = EditorGUIUtility.IconContent(open ? "IN foldout on" : "d_IN_foldout");
            icon.text = Localization.FindName("Surface Options");
            DrawFoldoutGUI(btnRect, icon, new Color(0.75f, 0.75f, 0.75f, 1), true);

            if (!open)
                return;

            if (_surfaceTypeProp == null && _cullProp == null && _zTestProp == null && _alphaClipProp == null && _receiveShadowsProp == null && _basePropertyAttributes.Count == 0 && _selectPropertyAttributes.Count == 0)
            {
                EditorGUILayout.HelpBox(Localization.GetLocalize() ? "这个着色器没有这种类型的参数！" : "This shader does not have this type of parameter！", MessageType.None);
                return;
            }

            SurfaceTypeGUI();
            RenderFaceGUI();
            DepthTestGUI();
            AlphaClippingGUI();
            ReceiveShadowsGUI();
            BaseToggleGUI();
            SelectToggleGUI();
        }

        /// <summary> 表面类型绘制 </summary>
        void SurfaceTypeGUI()
        {
            if (_surfaceTypeProp == null)
                return;

            // ------ 表面选择 -------
            // 0    Opaque
            // 1    Transparent
            EditorGUI.BeginChangeCheck();
            var surfaceType = _materialEditor.PopupShaderProperty(_surfaceTypeProp, Localization.FindName("Surface Type"), Enum.GetNames(typeof(SurfaceType)));
            if (EditorGUI.EndChangeCheck() || _firstEnable)
            {
                foreach (var mat in _materials)
                    SetSurfaceMode(mat);
            }

            // ------ 混合模式选择 -------
            // 0        Alpha,          旧的的阿尔法混合模式，菲涅尔不影响透明度
            // 1        Premultiply,    物理上合理的透明模式，实现为alpha预乘法
            // 2        Additive,       添加混合模式
            // 3        Multiply        相乘混合模式
            if ((SurfaceType)surfaceType != SurfaceType.Transparent)
                return;

            if (_blendProp == null)
            {
                LogMessage(" Shader 中存在 _Surface 选项属性，但不存在 _Blend 选项属性。这是不规范的代码逻辑，请及时修改！！！", _material.shader);
                return;
            }

            EditorGUI.BeginChangeCheck();
            var blendMode = (BlendMode)_materialEditor.PopupShaderProperty(_blendProp, Localization.FindName("Blending Mode"), Enum.GetNames(typeof(BlendMode)));
            if (EditorGUI.EndChangeCheck() || _firstEnable)
            {
                foreach (var mat in _materials)
                    SetBlendMode(mat);
            }

            // ------ 混合模式保持高光 项兼容Lit Shader -------
            if (!_material.HasProperty(CommonProperty.BlendModePreserveSpecular) || (blendMode != BlendMode.Alpha && blendMode != BlendMode.Additive))
                return;

            EditorGUI.BeginChangeCheck();
            EditorGUI.indentLevel++;
            _materialEditor.ToggleShaderProperty(_blendModePreserveSpecularProp, Localization.FindName("Preserve Specular Lighting"));
            EditorGUI.indentLevel--;

            if (!EditorGUI.EndChangeCheck() && !_firstEnable)
                return;

            foreach (var mat in _materials)
                SetPreserveSpecularLighting(mat);
        }

        /// <summary> 渲染面GUI </summary>
        void RenderFaceGUI()
        {
            if (_cullProp == null)
                return;

            EditorGUI.BeginChangeCheck();
            _materialEditor.PopupShaderProperty(_cullProp, Localization.FindName("Render Face"), Enum.GetNames(typeof(RenderFace)));
            if (!EditorGUI.EndChangeCheck() && !_firstEnable)
                return;

            foreach (var mat in _materials)
                mat.doubleSidedGI = (RenderFace)TryGetMatFloat(mat, CommonProperty.Cull, 2) == RenderFace.Both;
        }

        /// <summary> 深度测试绘制 </summary>
        void DepthTestGUI()
        {
            if (_zTestProp == null)
                return;

            _materialEditor.PopupShaderProperty(_zTestProp, Localization.FindName("Depth Compare"), Enum.GetNames(typeof(UnityEngine.Rendering.CompareFunction)));
        }

        /// <summary> AlphaTest 测试 </summary>
        void AlphaClippingGUI()
        {
            if (_alphaClipProp == null)
                return;

            EditorGUI.BeginChangeCheck();
            var alphaClip = _materialEditor.ToggleShaderProperty(_alphaClipProp, Localization.FindName("Alpha Clipping"));
            if (EditorGUI.EndChangeCheck() || _firstEnable)
            {
                foreach (var mat in _materials)
                    SetAlphaClipping(mat);
            }

            if (!alphaClip)
                return;

            if (_cutoffProp == null)
            {
                LogMessage($"{_material.shader.name} 中存在 _AlphaClip 选项属性，但不存在 _Cutoff 属性。这是不规范的代码逻辑，请及时修改！！！");
                return;
            }

            EditorGUI.indentLevel++;
            _materialEditor.RangeProperty(_cutoffProp, Localization.FindName("Threshold"));
            EditorGUI.indentLevel--;
        }

        /// <summary> 接收阴影绘制 </summary>
        void ReceiveShadowsGUI()
        {
            if (_receiveShadowsProp == null)
                return;

            EditorGUI.BeginChangeCheck();
            _materialEditor.ToggleShaderProperty(_receiveShadowsProp, Localization.FindName("Receive Shadows"));

            if (!EditorGUI.EndChangeCheck() && !_firstEnable)
                return;

            foreach (var mat in _materials)
                SetReceiveShadows(mat);
        }

        /// <summary> 基础标签开关 </summary>
        void BaseToggleGUI()
        {
            foreach (var data in _basePropertyAttributes)
            {
                EditorGUI.BeginChangeCheck();
                _materialEditor.ToggleShaderProperty(data.property, Localization.FindName(data.property.displayName));
                if (!EditorGUI.EndChangeCheck() && !_firstEnable)
                    continue;

                if ((int)data.property.floatValue == 1)
                {
                    foreach (var mat in _materials)
                        TryEnableKeyword(mat, data.keywords[0]);
                }
                else
                {
                    foreach (var mat in _materials)
                        TryDisableKeyword(mat, data.keywords[0]);
                }
            }
        }

        /// <summary> 挑选标签开关 </summary>
        void SelectToggleGUI()
        {
            if (_selectPropertyAttributes.Count == 0)
                return;

            _layersStyle ??= new GUIStyle("ObjectPickerResultsEven").SetAlignment(TextAnchor.MiddleCenter);
            EditorGUILayout.LabelField(Localization.FindName("Layers"), _layersStyle);
            EditorGUILayout.BeginVertical("box");
            foreach (var data in _selectPropertyAttributes)
                _materialEditor.ToggleShaderProperty(data.property, Localization.FindName(data.property.displayName));

            EditorGUILayout.EndVertical();
        }
    }
}